home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / Open Transport / Sample Code / DLPI / ATM PCI DLPI / Sources / HWSpecific.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-03  |  13.3 KB  |  442 lines  |  [TEXT/MPS ]

  1. /***********************************************************
  2.     File:        HWSpecific.c
  3.  
  4.     Contains:    ATM PCI hardware specific code
  5.     
  6.     Written by:    
  7.  
  8.     Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.     
  12.     To Do:
  13.  ***********************************************************/
  14.  
  15. /***********************************************************
  16.   DEFINES
  17.  ***********************************************************/
  18.  
  19. /***********************************************************
  20.   INCLUDES
  21.  ***********************************************************/
  22.  
  23. #include "PCIRoutines.h"
  24. #include "HWSpecific.h"
  25.  
  26. /***********************************************************
  27.   FUNCTION PROTOTYPES
  28.  ***********************************************************/
  29.  
  30. Boolean ABCVendorIsThisOurCard(RegEntryID *theID, UInt32 cardAddress);
  31. Boolean ABCVendorInit(RegEntryID *theID);
  32. void ABCVendorTerminate(void);
  33. SInt32 ABCVendorSetATMAddress(UInt8 *physicalAddress);
  34. void ABCVendorGetFactoryATMAddress(UInt8 *addressArray);
  35. UInt32 ABCVendorGetPeakCellRate();
  36. OSStatus ABCVendorTransmit(ConnectTableEntry* conn, UInt16 vpi, UInt16 vci, mblk_t* mp);
  37. OSStatus ABCVendorActivateVCI(ConnectTableEntry* conn);
  38. OSStatus ABCVendorDeactivateVCI(ConnectTableEntry* conn);
  39.  
  40. static pascal void ABCVendorTxDTCallback(void *theParam);
  41. static pascal void ABCVendorRxDTCallback(void *theParam);
  42.  
  43. InterruptMemberNumber ABCVendorISR(InterruptSetMember member, void *refCon, UInt32 theIntCount);
  44.  
  45. /***********************************************************
  46.   GLOBALS
  47.  ***********************************************************/
  48.  
  49. static ABCVendorCardSpecific*     gABCVendorCardSpecificData;
  50.  
  51. #ifdef LOOPBACK_TEST
  52. // temporary static data structure used for loopback testing.
  53. static struct _LoopBackMessageInfo {
  54.     mblk_t*        mp;
  55.     UInt16        vpi;
  56.     UInt16        vci;
  57. } gLoopBackMessageInfo;
  58. #endif
  59.  
  60. /***********************************************************
  61.   EXTERNS
  62.  ***********************************************************/
  63.  
  64. extern    PortPrivateData *gPortPrivateData;
  65.  
  66. /*
  67. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  68. +                                                          +
  69. +  F U N C T I O N S                                       +
  70. +                                                          +
  71. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  72. */
  73.  
  74. //-----------------------------------------------------------------------------------------
  75. //    Description:
  76. //        This routine should determine if the card pointed to by theID can be used
  77. //        by this driver.  Before we can talk to the card, the card must be enabled.  To
  78. //        enable the card use the Expansion Manager calls to "set" the appropriate
  79. //        address space bit for your card.  
  80. //
  81. //        Always turn off the card after the test has been made.  Just because this routine
  82. //        is executed, it does not mean that the card is going to be used by the system.
  83. //        
  84. //    Input:
  85. //        theID - NameRegistry ID of our pci card
  86. //        cardAddress - base address of our pci card
  87. //
  88. //    Output:
  89. //        returns true, if driver can work with the card
  90. //        returns false, if driver cannot work with the card
  91. //
  92. //-----------------------------------------------------------------------------------------
  93. Boolean ABCVendorIsThisOurCard(RegEntryID *theID, UInt32 cardAddress)
  94. {
  95.     UInt16    commandValue, newCommandValue, readValue;
  96.     OSErr    error;
  97.     
  98.     error = ExpMgrConfigReadWord(theID, kPCIConfigCommandRegister,&commandValue);
  99.     newCommandValue = commandValue | kIOSpaceEnableBit;    // turn on the card i/o space
  100.     error = ExpMgrConfigWriteWord(theID, kPCIConfigCommandRegister, newCommandValue);
  101.      
  102.     // CARD REGISTERS ARE NOW ACCESSIBLE!
  103.     
  104.     // For I/O mapped cards...
  105.     // In this example the readValue will be byte swapped by the Expansion Manager so it will
  106.     // be in Big Endian format.  You don't have to swap anything.
  107.     
  108.     // error = ExpMgrIOReadWord(theID, (LogicalAddress )(cardAddress + offset to your register) ,&readValue);
  109.     
  110.     
  111.     
  112.     // For memory mapped cards...
  113.     // Since the card uses memory space, we can use the card using simple C pointers.  
  114.     // Remember that the card is little endian and the processor is big endian.
  115.     // Long words (32 bits) and words (16 bits) must be swapped.
  116.     
  117.     // readValue = *((UInt16 *)(cardAddress + offset to your register));
  118.      
  119.         // turn card back off
  120.     error = ExpMgrConfigWriteWord(theID, kPCIConfigCommandRegister, commandValue);
  121.     
  122.     return kTrue;
  123. }
  124.  
  125. //-----------------------------------------------------------------------------------------
  126. //    Description:
  127. //        This routine first trys to allocate memory for our gABCVendorCardSpecificData.The 
  128. //        hardware should then be initialized. This routine also installs the interrupt
  129. //        and initailizes the deferred task handlers.
  130. //
  131. //    Input:
  132. //
  133. //    Output:
  134. //        kTrue, if initialization was successfull
  135. //        kFalse, if initialization was not successfull
  136. //
  137. //-----------------------------------------------------------------------------------------
  138.  
  139. Boolean ABCVendorInit(RegEntryID *theID)
  140. {
  141.     OSStatus    err;
  142.     UInt32        spaceAllocated;
  143.  
  144. #ifdef LOOPBACK_TEST
  145.     gLoopBackMessageInfo.mp = (mblk_t*) NULL;
  146. #endif
  147.  
  148.     gABCVendorCardSpecificData = (ABCVendorCardSpecific*) PoolAllocateResident(sizeof(ABCVendorCardSpecific), kTrue);
  149.     if (gABCVendorCardSpecificData == NULL) return kFalse;
  150.     
  151.     gPortPrivateData->cardSpecific = gABCVendorCardSpecificData;
  152.  
  153.     /*
  154.      * kPCIConfigBase14Offset is the address at which the control
  155.      * registers are mapped.
  156.      */
  157.     GetPCICardBaseAddress(&(gPortPrivateData->nodeEntryID), &(gABCVendorCardSpecificData->cardBaseAddr),
  158.                                 kPCIConfigBase14Offset, &spaceAllocated);    
  159.         
  160.  
  161.     // initialize hardware, remember to turn on the address map bit in the Config Command Register
  162.     //    also if the card does dma then you need to turn on the dma bit
  163.     
  164.     
  165.     gPortPrivateData->TxDeferredTaskCookie = OTCreateDeferredTask(ABCVendorTxDTCallback, NULL);
  166.     gPortPrivateData->RxDeferredTaskCookie = OTCreateDeferredTask(ABCVendorRxDTCallback, NULL);
  167.  
  168.     // register interrupt handlers
  169.     err = InstallISR();
  170.     if (err != noErr)
  171.         return kFalse;
  172.     
  173.     return kTrue;
  174. }
  175.  
  176. //-----------------------------------------------------------------------------------------
  177. //    Description:
  178. //        This routine closes down the hardware.  The memory for gABCVendorCardSpecificData is   
  179. //        deallocated. This routine undoes everything done in the initialize routine.
  180. //
  181. //    Input:
  182. //        NONE
  183. //
  184. //    Output:
  185. //        NONE
  186. //
  187. //-----------------------------------------------------------------------------------------
  188.  
  189. void ABCVendorTerminate(void)
  190. {
  191.     OSStatus    err;
  192.     mblk_t    *thePacket;
  193.     
  194.     // turn off hardware
  195.     
  196.     // unregister interrupt handlers
  197.     err = UninstallISR();        // ignore the error right now!
  198.     
  199.     
  200.     OTDestroyDeferredTask(gPortPrivateData->TxDeferredTaskCookie);
  201.     OTDestroyDeferredTask(gPortPrivateData->RxDeferredTaskCookie);
  202.     
  203. }
  204.  
  205. //-----------------------------------------------------------------------------------------
  206. //    Description:
  207. //        This routine should set the physical address in the ATM hw.  On initialization
  208. //        we may have read our physical address out of a EPROM, but now somebody is 
  209. //        explicitly telling us to change our address.
  210. //
  211. //    Input:
  212. //        physicalAddress - multicast address (array of 6 bytes)
  213. //
  214. //    Output:
  215. //        returns no error
  216. //
  217. //-----------------------------------------------------------------------------------------
  218.  
  219. SInt32 ABCVendorSetATMAddress(UInt8 *physicalAddress)
  220. {
  221.     /* set the ATM NIC physical address */
  222.     return kOTNoError;
  223. }
  224.  
  225. //-----------------------------------------------------------------------------------------
  226. //    Description:
  227. //        This routine retrieves the factory ATM address.
  228. //
  229. //    Input:
  230. //        addressArray - address to place the factory ethernet address bytes
  231. //
  232. //    Output:
  233. //        NONE
  234. //
  235. //-----------------------------------------------------------------------------------------
  236. void ABCVendorGetFactoryATMAddress(UInt8 *addressArray)
  237. {
  238.     /* get the ATM NIC physical address */
  239.     addressArray[0] = 0x08;
  240.     addressArray[1] = 0x00;
  241.     addressArray[2] = 0x07;
  242.     addressArray[3] = 0x11;
  243.     addressArray[4] = 0x22;
  244.     addressArray[5] = 0x33;
  245. }
  246.  
  247. //-----------------------------------------------------------------------------------------
  248. //    Description:
  249. //        This routine retrieves the cards user peak cell rate in
  250. //        terms of cells/second.
  251. //
  252. //    Input:
  253. //        NONE
  254. //
  255. //    Output:
  256. //        Peak Cell Rate.
  257. //
  258. //-----------------------------------------------------------------------------------------
  259. UInt32 ABCVendorGetPeakCellRate()
  260. {
  261.     UInt32    rate;
  262.  
  263. //    rate = 365566;        /* 155 Mb/s */
  264.     rate = 330187;        /* 140 Mb/s */
  265. //    rate = 235849;        /* 100 Mb/s */
  266.  
  267.     return rate;
  268. }
  269.  
  270. //-----------------------------------------------------------------------------------------
  271. //    Description:
  272. //        This routine transmits an mp on the specfied vpi,vci.
  273. //
  274. //    Input:
  275. //        vpi - Virtual Path Identifier
  276. //        vci - Virtual Circuit Identifier
  277. //        mp    - mblk to transmit
  278. //
  279. //    Output:
  280. //        kOTNoError, if good transmission
  281. //        kFlowControl, if the VC can not accept the data.
  282. //
  283. //-----------------------------------------------------------------------------------------
  284. OSStatus ABCVendorTransmit(ConnectTableEntry* conn, UInt16 vpi, UInt16 vci, mblk_t* mp)
  285. {
  286.     // Some drivers may have a more efficient way of retrieving
  287.     // the connect table entry given the vpi and vci.
  288.     if (conn==NULL)
  289.         conn = find_connection(vpi, vci, kVCIOut);
  290.  
  291.     // transmit the message mp
  292.  
  293. #ifdef LOOPBACK_TEST
  294.     // this is for the loopback test
  295.     if (gLoopBackMessageInfo.mp == (mblk_t*) NULL) {
  296.         gLoopBackMessageInfo.mp = copymsg(mp);
  297.         gLoopBackMessageInfo.vpi = vpi;
  298.         gLoopBackMessageInfo.vci = vci;
  299.         OTScheduleDeferredTask(gPortPrivateData->RxDeferredTaskCookie);
  300.     }
  301. #endif
  302.  
  303.     freemsg(mp);
  304.  
  305.     return kOTNoError;
  306. }
  307.  
  308.  
  309. //-----------------------------------------------------------------------------------------
  310. //    Description:
  311. //        This routine activates the vpi,vci refered to
  312. //        by the ConnectTableEntry specified.
  313. //
  314. //    Input:
  315. //        conn - ConnectTableEntry for VC to be activated
  316. //
  317. //    Output:
  318. //        kOTNoError
  319. //
  320. //-----------------------------------------------------------------------------------------
  321. OSStatus ABCVendorActivateVCI(ConnectTableEntry* conn)
  322. {
  323.     // enable a VCI on the NIC
  324.  
  325.     return kOTNoError;
  326. }
  327.  
  328. //-----------------------------------------------------------------------------------------
  329. //    Description:
  330. //        This routine deactivates the vpi,vci refered to
  331. //        by the ConnectTableEntry specified.
  332. //
  333. //    Input:
  334. //        conn - ConnectTableEntry for VC to be activated
  335. //
  336. //    Output:
  337. //        kOTNoError
  338. //
  339. //-----------------------------------------------------------------------------------------
  340. OSStatus ABCVendorDeactivateVCI(ConnectTableEntry* conn)
  341. {
  342.     // disable a VCI on the NIC
  343.  
  344.     return kOTNoError;
  345. }
  346.  
  347. //-----------------------------------------------------------------------------------------
  348. //    Description:
  349. //        This routine processes a deferred task caused due to
  350. //        a transmission completion.
  351. //
  352. //    Input:
  353. //        theParam - the parameter passed when creating the
  354. //                    deferred task cookie, which is NULL in our case.
  355. //
  356. //    Output:
  357. //        NONE
  358. //
  359. //-----------------------------------------------------------------------------------------
  360. static pascal void ABCVendorTxDTCallback(void *theParam)
  361. {
  362.  
  363.     // free the last transmitted message
  364.  
  365. }
  366.  
  367. //-----------------------------------------------------------------------------------------
  368. //    Description:
  369. //        This routine processes a deferred task caused due to
  370. //        a packet reception. This routine should form an mblk
  371. //        with the received packet and call ATMDLPI_unitdata_ind().
  372. //
  373. //    Input:
  374. //        theParam - the parameter passed when creating the
  375. //                    deferred task cookie, which is NULL in our case.
  376. //
  377. //    Output:
  378. //        NONE
  379. //
  380. //-----------------------------------------------------------------------------------------
  381. static pascal void ABCVendorRxDTCallback(void *theParam)
  382. {
  383.     // get the received message from the card, create
  384.     // a message block and send it up using
  385.     // ATMDLPI_unitdata_ind()
  386.  
  387. #ifdef LOOPBACK_TEST
  388.     // this is for the loopback test
  389.     if (gLoopBackMessageInfo.mp) {
  390.         ATMDLPI_unitdata_ind((ConnectTableEntry*) NULL, gLoopBackMessageInfo.vpi, gLoopBackMessageInfo.vci,
  391.                                                                 gLoopBackMessageInfo.mp);
  392.         gLoopBackMessageInfo.mp = (mblk_t*) NULL;
  393.     }
  394. #endif
  395. }
  396.  
  397. //-----------------------------------------------------------------------------------------
  398. //    Description:
  399. //        This routine is the interrupt service routine for our card.  Do necessary 
  400. //        stuff in isr then defer for a later time the bulk of the work.  In the isr
  401. //        you need to notify Open Transport that we are in an isr.  The next step
  402. //        is to clear whatever hw bit you need to in order to deassert the interrupt line.
  403. //        
  404. //    Input:
  405. //        member - contains information about the pci interrupt member
  406. //        refCon - this value was passed in during the installation of the isr, since
  407. //                we have globals we do not need to use this
  408. //
  409. //    Output:
  410. //        return kIsrIsComplete always
  411. //
  412. //-----------------------------------------------------------------------------------------
  413.  
  414. InterruptMemberNumber ABCVendorISR(InterruptSetMember member, void *refCon, UInt32 theIntCount)
  415. {
  416.     mblk_t            *thePacket;
  417.     
  418.     OTEnterInterrupt();                    // open transport needs to be notified
  419.                                         //  when entering an interrupt
  420.     
  421.     // clear the bit that caused the interrupt
  422.     
  423.         
  424.     if (0 /* it is a transmit interrupt */) {
  425.     
  426.         OTScheduleDeferredTask(gPortPrivateData->TxDeferredTaskCookie);
  427.  
  428.     }
  429.     
  430.     if (1 /* it is a receive interrupt */) {
  431.     
  432.         OTScheduleDeferredTask(gPortPrivateData->RxDeferredTaskCookie);
  433.  
  434.     }
  435.     
  436.     
  437.     OTLeaveInterrupt();                    // open transport needs to be notified
  438.                                         //  when leaving an interrupt
  439.     return kIsrIsComplete;
  440. }
  441.  
  442.